/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.coheigea.cxf.sts.xacml.pdp.xacml2; import java.util.List; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.rt.security.saml.xacml.XACMLConstants; import org.apache.wss4j.common.ext.WSSecurityException; import org.apache.wss4j.common.saml.OpenSAMLUtil; import org.opensaml.core.xml.XMLObjectBuilderFactory; import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; import org.opensaml.xacml.XACMLObjectBuilder; import org.opensaml.xacml.ctx.AttributeType; import org.opensaml.xacml.ctx.DecisionType; import org.opensaml.xacml.ctx.RequestType; import org.opensaml.xacml.ctx.ResponseType; import org.opensaml.xacml.ctx.ResultType; import org.opensaml.xacml.ctx.StatusCodeType; import org.opensaml.xacml.ctx.StatusType; import org.opensaml.xacml.ctx.SubjectType; /** * A testXACML 2.0 PDP implementation based on OpenSAML 2.0. It just mocks up a Response * object based on the role of the Subject. If the role is "boss" then it permits the * request, otherwise it denies it. */ @Path("/pdp") public class MockPDPImpl { @POST public Source evaluate(Source request) { RequestType requestType = requestSourceToRequestType(request); XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory(); @SuppressWarnings("unchecked") XACMLObjectBuilder<ResponseType> responseTypeBuilder = (XACMLObjectBuilder<ResponseType>) builderFactory.getBuilder(ResponseType.DEFAULT_ELEMENT_NAME); @SuppressWarnings("unchecked") XACMLObjectBuilder<ResultType> resultTypeBuilder = (XACMLObjectBuilder<ResultType>) builderFactory.getBuilder(ResultType.DEFAULT_ELEMENT_NAME); @SuppressWarnings("unchecked") XACMLObjectBuilder<DecisionType> decisionTypeBuilder = (XACMLObjectBuilder<DecisionType>) builderFactory.getBuilder(DecisionType.DEFAULT_ELEMENT_NAME); @SuppressWarnings("unchecked") XACMLObjectBuilder<StatusType> statusTypeBuilder = (XACMLObjectBuilder<StatusType>) builderFactory.getBuilder(StatusType.DEFAULT_ELEMENT_NAME); @SuppressWarnings("unchecked") XACMLObjectBuilder<StatusCodeType> statusCodeTypeBuilder = (XACMLObjectBuilder<StatusCodeType>) builderFactory.getBuilder(StatusCodeType.DEFAULT_ELEMENT_NAME); DecisionType decisionType = decisionTypeBuilder.buildObject(); String role = getSubjectRole(requestType); if ("boss".equals(role)) { decisionType.setDecision(DecisionType.DECISION.Permit); } else { decisionType.setDecision(DecisionType.DECISION.Deny); } ResultType result = resultTypeBuilder.buildObject(); result.setDecision(decisionType); StatusType status = statusTypeBuilder.buildObject(); StatusCodeType statusCode = statusCodeTypeBuilder.buildObject(); statusCode.setValue("urn:oasis:names:tc:xacml:1.0:status:ok"); status.setStatusCode(statusCode); result.setStatus(status); ResponseType response = responseTypeBuilder.buildObject(); response.getResults().add(result); return responseType2Source(response); } private RequestType requestSourceToRequestType(Source requestSource) { try { Transformer trans = TransformerFactory.newInstance().newTransformer(); DOMResult res = new DOMResult(); trans.transform(requestSource, res); Node nd = res.getNode(); if (nd instanceof Document) { nd = ((Document)nd).getDocumentElement(); } return (RequestType)OpenSAMLUtil.fromDom((Element)nd); } catch (Exception e) { throw new RuntimeException("Error converting pdp response to ResponseType", e); } } private Source responseType2Source(ResponseType response) { Document doc = DOMUtils.createDocument(); Element responseElement; try { responseElement = OpenSAMLUtil.toDom(response, doc); } catch (WSSecurityException e) { throw new RuntimeException("Error converting PDP RequestType to Dom", e); } return new DOMSource(responseElement); } private String getSubjectRole(RequestType request) { List<SubjectType> subjects = request.getSubjects(); if (subjects != null) { for (SubjectType subject : subjects) { List<AttributeType> attributes = subject.getAttributes(); if (attributes != null) { for (AttributeType attribute : attributes) { if (XACMLConstants.SUBJECT_ROLE.equals(attribute.getAttributeId())) { return attribute.getAttributeValues().get(0).getValue(); } } } } } return null; } }